package rss_GUI;

import java.awt.Toolkit;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import java.util.ArrayList;
import java.util.List;

import rss_CODE.RadioStationSystem;
import rss_POJO.*;

/**
 *
 * @author RS-team
 */
public class AvailableSongsTable extends javax.swing.JFrame {

    private final RadioStationSystem rss;
    private final EntityManager em;
    private final PlayListManagement plm;
    private final MainMenu mm;

    private Song s;

    
    /**
     * Creates new form AvailableSongsTable
     */
    public AvailableSongsTable(PlayListManagement plm, MainMenu mm) {
        this.rss = mm.getRSS();
        this.em = mm.getEM();
        this.mm = mm;
        this.plm = plm;
        initComponents();

        jScrollPaneFORM.setVerticalScrollBarPolicy(jScrollPaneFORM.VERTICAL_SCROLLBAR_ALWAYS);
    }

    /* dynamic jpql query που επιστρέφει εγγραφές από το table Song βάσει ελευθέρου κριτηρίου αναζήτησης */
    private List<Song> searchForSongs(String criteria) {
        try {
            return em.createQuery("SELECT s FROM Song s WHERE LOWER(s.title) LIKE ?1 ", Song.class)
                                                    .setParameter(1, "%"+criteria+"%").getResultList();
        } catch(NoResultException nrex) {
            // δεν βρέθηκε τίποτα, για αποφυγή πιθανών null exceptions, επέστρεψε μία κενή λίστα
            return org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Song>());
        } catch(Exception ex) {
            // γενικότερο σφάλμα σύνθεσης ή εκτέλεσης query αναζήτησης Song
            rss.criticalErrorBox(this, "σφάλμα query αναζήτησης SONGs βάσει κριτηρίων  ");
            // αγνοώντας οποιαδήποτε πιθανά νέα Exceptions προκύψουν,...
            try {
                em.close();  // οριστικό κλείσιμο EntityManager em
            } catch (Exception e) {
                // τίποτα πλέον, έτσι κι αλλιώς πάμε για κλείσιμο
            } finally {
                System.exit(5);  // έξοδος με errorlevel 5
                return null;  // άχρηστο αλλά αναγκαίο
            }
        } 
    }
   
 
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        try {
            querySong = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT s FROM Song s");
            listSong = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(querySong.getResultList());
        } catch(Exception ex) {
            rss.warningBox(this, "σφάλμα κατά την ανάγνωση SONGs");
            // αν υπάρχει προηγούμενη την μηδενίζω και την στέλνω στον GC, κατόπιν δημιουργώ και επιστρέφω νέα κενή λίστα λόγω γενικότερου σφάλματος
            if(listSong != null) listSong.clear(); listSong = null; listSong = org.jdesktop.observablecollections.ObservableCollections.observableList(new ArrayList<Song>());
        }
        jPanelFORM = new javax.swing.JPanel();
        txtCriteria = new javax.swing.JTextField();
        jScrollPaneFORM = new javax.swing.JScrollPane();
        SongsTABLE = new javax.swing.JTable();
        SongsTABLE.setSelectionModel(new MainMenu.ForcedListSelectionModel());

        SongsTABLE.getTableHeader().addMouseListener(new MainMenu.TableHeaderMouseListener(SongsTABLE));
        jButtonSEARCHSONG = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("RADIO STATION SYSTEM - Διαθέσιμα Τραγούδια");
        setFocusable(false);
        setLocationByPlatform(true);
        setMinimumSize(new java.awt.Dimension(606, 258));
        setName("SONGsAVAILABLE"); // NOI18N
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().setLayout(null);

        jPanelFORM.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanelFORM.setEnabled(false);
        jPanelFORM.setPreferredSize(new java.awt.Dimension(720, 180));

        txtCriteria.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        txtCriteria.setBorder(javax.swing.BorderFactory.createTitledBorder("ΚΡΙΤΗΡΙΑ ΑΝΑΖΗΤΗΣΗΣ  ( % as wildcard, _ for single character, case insensitive)"));

        jScrollPaneFORM.setBorder(javax.swing.BorderFactory.createTitledBorder("ΠΕΡΙΕΧΟΜΕΝΑ ΛΙΣΤΑΣ ΤΡΑΓΟΥΔΙΩΝ"));
        jScrollPaneFORM.setFocusable(false);
        jScrollPaneFORM.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jScrollPaneFORM.setMinimumSize(new java.awt.Dimension(31, 31));
        jScrollPaneFORM.setPreferredSize(new java.awt.Dimension(462, 155));
        jScrollPaneFORM.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jScrollPaneFORMMousePressed(evt);
            }
        });

        SongsTABLE.setAutoCreateRowSorter(true);
        SongsTABLE.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        SongsTABLE.setFocusable(false);

        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, listSong, SongsTABLE);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${title}"));
        columnBinding.setColumnName("ΤΙΤΛΟΣ ΤΡΑΓΟΥΔΙΟΥ");
        columnBinding.setColumnClass(String.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${albumId}"));
        columnBinding.setColumnName("ΚΑΛΛΙΤΕΧΝΗΣ/ΣΥΓΚΡΟΤΗΜΑ");
        columnBinding.setColumnClass(rss_POJO.Album.class);
        columnBinding.setEditable(false);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${duration}"));
        columnBinding.setColumnName("ΔΙΑΡΚΕΙΑ");
        columnBinding.setColumnClass(Integer.class);
        columnBinding.setEditable(false);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        SongsTABLE.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                SongsTABLEMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                SongsTABLEMousePressed(evt);
            }
        });
        SongsTABLE.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                SongsTABLEKeyPressed(evt);
            }
        });
        jScrollPaneFORM.setViewportView(SongsTABLE);
        if (SongsTABLE.getColumnModel().getColumnCount() > 0) {
            SongsTABLE.getColumnModel().getColumn(0).setMinWidth(140);
            SongsTABLE.getColumnModel().getColumn(1).setMinWidth(186);
            SongsTABLE.getColumnModel().getColumn(1).setCellRenderer(new MainMenu.AlbumIDCellRenderer());
            SongsTABLE.getColumnModel().getColumn(2).setMinWidth(74);
            SongsTABLE.getColumnModel().getColumn(2).setPreferredWidth(74);
            SongsTABLE.getColumnModel().getColumn(2).setMaxWidth(74);
            SongsTABLE.getColumnModel().getColumn(2).setCellRenderer(new MainMenu.TimeDurationCellRenderer());
        }

        jButtonSEARCHSONG.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jButtonSEARCHSONG.setIcon(new javax.swing.ImageIcon(getClass().getResource("/misc/design/_Search.png"))); // NOI18N
        jButtonSEARCHSONG.setText("Αναζήτηση");
        jButtonSEARCHSONG.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButtonSEARCHSONG.setFocusable(false);
        jButtonSEARCHSONG.setIconTextGap(8);
        jButtonSEARCHSONG.setInheritsPopupMenu(true);
        jButtonSEARCHSONG.setMargin(new java.awt.Insets(2, 0, 2, 0));
        jButtonSEARCHSONG.setMaximumSize(new java.awt.Dimension(100, 30));
        jButtonSEARCHSONG.setMinimumSize(new java.awt.Dimension(100, 30));
        jButtonSEARCHSONG.setPreferredSize(new java.awt.Dimension(100, 30));
        jButtonSEARCHSONG.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSEARCHSONGActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelFORMLayout = new javax.swing.GroupLayout(jPanelFORM);
        jPanelFORM.setLayout(jPanelFORMLayout);
        jPanelFORMLayout.setHorizontalGroup(
            jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelFORMLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPaneFORM, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanelFORMLayout.createSequentialGroup()
                        .addComponent(txtCriteria, javax.swing.GroupLayout.PREFERRED_SIZE, 456, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jButtonSEARCHSONG, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanelFORMLayout.setVerticalGroup(
            jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelFORMLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelFORMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtCriteria, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonSEARCHSONG, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPaneFORM, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        getContentPane().add(jPanelFORM);
        jPanelFORM.setBounds(0, 0, 600, 230);

        getAccessibleContext().setAccessibleName("RADIO STATION SYSTEM - Διαθέσιμα Τραγούδια");

        bindingGroup.bind();

        pack();
    }// </editor-fold>//GEN-END:initComponents
   
    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        System.out.println("~AvailableSongsTable is ON");
    }//GEN-LAST:event_formWindowOpened

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        System.out.println(" ~ButtonX");
        this.toBack(); dispose();  // στείλε το παράθυρο στο background και κλείσε το AvailableSongsTable
        System.out.println(" ~AvailableSongsTable by X");
    }//GEN-LAST:event_formWindowClosing

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        plm.setEnabled(true);  // έξοδος και ενεργοποίηση της PlayListManagement
        System.out.println("~AvailableSongsTable is now OFF");
    }//GEN-LAST:event_formWindowClosed

    private void jButtonSEARCHSONGActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSEARCHSONGActionPerformed
        System.out.println("  ~ButtonSEARCHSONG");
            listSong.clear(); listSong.addAll(searchForSongs(txtCriteria.getText().trim().toLowerCase()));
    }//GEN-LAST:event_jButtonSEARCHSONGActionPerformed

    private void SongsTABLEKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_SongsTABLEKeyPressed
        //System.out.println(evt.getKeyCode());
        if(evt.getKeyCode() == 32) { evt.setKeyCode(10); }  // επαναχαρτογράφηση Space key στο Enter key
        else if(evt.getKeyCode() == 10) {  // εξυπηρέτηση Enter key για εισαγωγή και ταυτόχρονη κύλιση προς τα κάτω
            int row = SongsTABLE.getSelectedRow();  // αποθήκευση επιλεγμένης γραμμής πίνακα Διαθέσιμων Τραγουδιών
            if(row != -1) {  // αν υπάρχει κάποιο Τραγούδι επιλεγμένο στον πίνακα Διαθέσιμών Τραγουδιών
                s = listSong.get(SongsTABLE.convertRowIndexToModel(row));  // αντιστοίχιση s τύπου Song στην επιλεγμένη γραμμή
                if(plm.getListSongsInPlayList().contains(s)) rss.warningBox(this, "το ΤΡΑΓΟΥΔΙ αυτό είναι ήδη καταχωρυμένο στη ΛΙΣΤΑ   ");  // το Τραγούδι είναι ήδη καταχωρυμένο
                else { plm.getListSongsInPlayList().add(s);  //  αλλιώς προσέθεσέ το
                    int totalDuration = 0; for(Song song : plm.getListSongsInPlayList()) totalDuration += song.getDuration(); plm.txtDuration.setText(rss.integerToTimeDuration(totalDuration) + " ");  // νέος υπολογισμός συνολικής διάρκειας Τραγουδιών της Λίστας
                }
            } else Toolkit.getDefaultToolkit().beep();
        }
    }//GEN-LAST:event_SongsTABLEKeyPressed

    private void SongsTABLEMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_SongsTABLEMousePressed
        SongsTABLE.setFocusable(true); SongsTABLE.grabFocus();  // focus στον πίνακα
    }//GEN-LAST:event_SongsTABLEMousePressed

    private void jScrollPaneFORMMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jScrollPaneFORMMousePressed
        SongsTABLE.getRowSorter().setSortKeys(null);  // κατάργηση ταξινόμησης
        // εμφάνιση viewport που να περιέχει την επιλεγμένη γραμμή και επικαιροποίηση του πίνακα
        SongsTABLE.scrollRectToVisible(SongsTABLE.getCellRect(SongsTABLE.getSelectedRow(), 0, true));
        SongsTABLE.repaint();
    }//GEN-LAST:event_jScrollPaneFORMMousePressed

    private void SongsTABLEMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_SongsTABLEMouseClicked
        if(evt.getClickCount() == 2) {  // εξυπηρέτηση double click
            int row = SongsTABLE.getSelectedRow();  // αποθήκευση επιλεγμένης γραμμής πίνακα Διαθέσιμων Τραγουδιών
            if(row != -1) {  // αν υπάρχει κάποιο Τραγούδι επιλεγμένο στον πίνακα Διαθέσιμών Τραγουδιών
                s = listSong.get(SongsTABLE.convertRowIndexToModel(row));  // αντιστοίχιση s τύπου Song στην επιλεγμένη γραμμή
                if(plm.getListSongsInPlayList().contains(s)) rss.warningBox(this, "το ΤΡΑΓΟΥΔΙ αυτό είναι ήδη καταχωρυμένο στη ΛΙΣΤΑ   ");  // το Τραγούδι είναι ήδη καταχωρυμένο
                else { plm.getListSongsInPlayList().add(s);  //  αλλιώς προσέθεσέ το
                    int totalDuration = 0; for(Song song : plm.getListSongsInPlayList()) totalDuration += song.getDuration(); plm.txtDuration.setText(rss.integerToTimeDuration(totalDuration) + " ");  // νέος υπολογισμός συνολικής διάρκειας Τραγουδιών της Λίστας
                }
            } else Toolkit.getDefaultToolkit().beep();
        }
    }//GEN-LAST:event_SongsTABLEMouseClicked

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTable SongsTABLE;
    private javax.swing.JButton jButtonSEARCHSONG;
    private javax.swing.JPanel jPanelFORM;
    private javax.swing.JScrollPane jScrollPaneFORM;
    private java.util.List<Song> listSong;
    private javax.persistence.Query querySong;
    private javax.swing.JTextField txtCriteria;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}